package cn.xinfei.xdecision.datasource.mysql.dynamic;

import cn.xinfei.xdecision.common.dynamic.DataSourceType;
import cn.xinfei.xdecision.datasource.mysql.DefaultDBFieldHandler;
import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import java.util.HashMap;
import java.util.Map;

/**
 * 此mysql实例存储数据类型信息，其他没有这类需求的此类不进行实例化
 */
@Slf4j
@Configuration
@ConditionalOnProperty(name = "spring.datasource.druid.dynamic.enable", matchIfMissing = false)
@MapperScan(basePackages = {"cn.xinfei.xdecision.common.datadao.**"}, sqlSessionTemplateRef = "sqlSessionTemplateDynamic")
public class DynamicDataMySQLTemplate {


    @Autowired
    private DefaultDBFieldHandler defaultDBFieldHandler;


    @Bean(name = "dynamicDataSource")
    public DynamicDatasource dynamicDataSource(
            @Qualifier("druidDataSourceExam") DruidDataSource druidDataSourceExam,
            @Qualifier("druidDataSourceData") DruidDataSource druidDataSourceData) {
        log.info("dynamicDataSource init ...");
        log.info("data source.db={}", druidDataSourceData.getRawJdbcUrl());
        log.info("exam source.db={}", druidDataSourceExam.getRawJdbcUrl());
        Map<Object, Object> targetDataSource = new HashMap<>();
        targetDataSource.put(DataSourceType.data, druidDataSourceData);
        targetDataSource.put(DataSourceType.exam, druidDataSourceExam);
        DynamicDatasource dataSource = new DynamicDatasource();
        dataSource.setTargetDataSources(targetDataSource);
        dataSource.setDefaultTargetDataSource(druidDataSourceData);
        return dataSource;
    }

    @Bean(name = "sqlSessionFactoryDynamic")
    public SqlSessionFactory sqlSessionFactoryDynamic(
            @Qualifier("dynamicDataSource") DynamicDatasource dynamicDataSource) throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        Resource[] mapperXmlResource = resolver.getResources("classpath*:cn/xinfei/xdecision/common/datadao/*Mapper.xml");
        bean.setMapperLocations(mapperXmlResource);
        bean.setDataSource(dynamicDataSource);
        log.info("dynamicDataSource source.db={}", dynamicDataSource);
        bean.setTypeAliasesPackage("cn.xinfei.xdecision.common.datamodel");
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setMetaObjectHandler(defaultDBFieldHandler);
        bean.setGlobalConfig(globalConfig);
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setCacheEnabled(false);
        bean.setConfiguration(configuration);
        return bean.getObject();
    }


    @Bean(name = "transactionManagerDynamic")
    public DataSourceTransactionManager transactionManagerDynamic(
            @Qualifier("dynamicDataSource") DynamicDatasource dynamicDataSource) {
        DataSourceTransactionManager dm = new DataSourceTransactionManager();
        dm.setDataSource(dynamicDataSource);
        return dm;
    }


    @Bean(name = "sqlSessionTemplateDynamic")
//    @ConditionalOnProperty( name = "spring.datasource.druid.data.enable")
    public SqlSessionTemplate sqlSessionTemplateDynamic(
            @Qualifier("sqlSessionFactoryDynamic") SqlSessionFactory sqlSessionFactoryDynamic) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactoryDynamic);
    }

}
